using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Pavilion;

namespace Pavilion.Control
{
    public enum StateOfButton
    {
        Inside,
        Outside,
        InsidePressed,
        OutsidePressed
    }

    public class Button : Control
    {
        #region //////////////////////////////////////////////Attributes//////////////////////////////////////////////

        private Rectangle normalBounds, shrinkBounds;
        private Color textColor;
        private Label textLabel;
        private StateOfButton currentButtonState;

        private Action<MouseCursor> LeftMousePressedDel, LeftMouseReleasedDel;
        public event Action Pressed;

        #endregion

        #region ////////////////////////////////////////////Initialization////////////////////////////////////////////

        public Button(string text, Rectangle bounds, float size) : base()
        {
            this.AreaBounds = bounds;
            textColor = Color.White;
            this.BackgroundColor = new Color(0, 0, 0, 0);
            currentButtonState = StateOfButton.Outside;

            normalBounds = new Rectangle(0, 0, bounds.Width, bounds.Height);
            shrinkBounds = new Rectangle();
            shrinkBounds.Width = (int)(normalBounds.Width * 0.9f);
            shrinkBounds.Height = (int)(normalBounds.Height * 0.9f);
            shrinkBounds.X = normalBounds.X + (int)(normalBounds.Width * ((1f - 0.9f) / 2));
            shrinkBounds.Y = normalBounds.Y + (int)(normalBounds.Height * ((1f - 0.9f) / 2));

            this.textLabel = new Label(text, normalBounds, new Color(128, 128, 128, 64));
            this.textLabel.TextSize = size;
            this._Collection.Add(this.textLabel);

            this.textLabel.Input.Enter += new EventHandler(Button_Enter);
            this.textLabel.Input.Leave += new EventHandler(Button_Leave);

            LeftMousePressedDel += new Action<MouseCursor>(Button_LeftMousePressed);
            LeftMouseReleasedDel += new Action<MouseCursor>(Button_LeftMouseReleased);

            this.IsActiveChanged += new Action<bool>(Button_IsActiveChanged);
        }

        #endregion

        #region ////////////////////////////////////////////////Methods///////////////////////////////////////////////


        private void SetButtonStateToOutside()
        {
            currentButtonState = StateOfButton.Outside;
            textLabel.BackgroundColor = new Color(128, 128, 128, 64);
            textLabel.OutlineColor = Color.Black;

            LeftMousePressed -= LeftMousePressedDel;
            LeftMouseReleased -= LeftMouseReleasedDel;
        }

        private void SetButtonStateToOutsidePressed()
        {
            currentButtonState = StateOfButton.OutsidePressed;
            textLabel.BackgroundColor = new Color(128, 128, 128, 128);
            textLabel.OutlineColor = Color.White;

            LeftMousePressed -= LeftMousePressedDel;
            LeftMouseReleased += LeftMouseReleasedDel;
        }

        private void SetButtonStateToInside()
        {
            currentButtonState = StateOfButton.Inside;
            textLabel.BackgroundColor = new Color(128, 128, 128, 128);
            textLabel.OutlineColor = Color.White;

            LeftMousePressed += LeftMousePressedDel;
            LeftMouseReleased -= LeftMouseReleasedDel;
        }

        private void SetButtonStateToInsidePressed()
        {
            currentButtonState = StateOfButton.InsidePressed;
            textLabel.BackgroundColor = new Color(128, 128, 128, 200);
            textLabel.OutlineColor = Color.White;

            RootControl.Instance.MouseCursor.LeftMousePressed -= LeftMousePressedDel;
            RootControl.Instance.MouseCursor.LeftMouseReleased += LeftMouseReleasedDel;
        }

        #endregion

        #region ////////////////////////////////////////////Gets and Sets/////////////////////////////////////////////

        /// <summary>
        /// Gets or sets the text Label of this Button.
        /// </summary>
        public Label TextLabel
        {
            get { return textLabel; }
            set { textLabel = value; }
        }

        /// <summary>
        /// Gets or Sets whether the functionality of the button is enabled.
        /// </summary>
        public override bool Enabled
        {
            get { return base.Enabled; }
            set
            {
                base.Enabled = value;

                if (Enabled)
                {
                    textLabel.BackgroundColor = new Color(128, 128, 128, 64);
                    textColor = Color.White;
                }
                else
                {
                    textLabel.BackgroundColor = new Color(128, 128, 128, 0);
                    textColor = new Color(128, 128, 128, 128);
                }
            }
        }

        #endregion

        #region ////////////////////////////////////////////////Events////////////////////////////////////////////////

        private event Action<MouseCursor> LeftMousePressed
        {
            add
            {
                if (!RootControl.Instance.MouseCursor.LeftMousePressedInvocationList.Contains(value))
                    RootControl.Instance.MouseCursor.LeftMousePressed += value;
            }
            remove
            {
                if (RootControl.Instance.MouseCursor.LeftMousePressedInvocationList.Contains(value))
                    RootControl.Instance.MouseCursor.LeftMousePressed -= value;
            }
        }

        private event Action<MouseCursor> LeftMouseReleased
        {
            add
            {
                if (!RootControl.Instance.MouseCursor.LeftMouseReleasedInvocationList.Contains(value))
                    RootControl.Instance.MouseCursor.LeftMouseReleased += value;
            }
            remove
            {
                if (RootControl.Instance.MouseCursor.LeftMouseReleasedInvocationList.Contains(value))
                    RootControl.Instance.MouseCursor.LeftMouseReleased -= value;
            }
        }

        private void OnPressed()
        {
            if (Pressed != null)
                Pressed();
        }

        private void Button_IsActiveChanged(bool isActive)
        {
            if (!IsActive)
                SetButtonStateToOutside();
        }

        private void Button_LeftMouseReleased(MouseCursor mouseCursor)
        {
            if (currentButtonState == StateOfButton.InsidePressed)
            {
                SetButtonStateToInside();
                OnPressed();
            }
            else
            {
                SetButtonStateToOutside();
            }
        }

        private void Button_LeftMousePressed(MouseCursor mouseCursor)
        {
            SetButtonStateToInsidePressed();
        }

        private void Button_Leave(object sender, EventArgs e)
        {
            if (currentButtonState == StateOfButton.InsidePressed)
                SetButtonStateToOutsidePressed();
            else
                SetButtonStateToOutside();
        }

        private void Button_Enter(object sender, EventArgs e)
        {
            if (currentButtonState == StateOfButton.OutsidePressed)
                SetButtonStateToInsidePressed();
            else
                SetButtonStateToInside();
        }

        #endregion
    }
}
